﻿using Abp.Authorization.Users;
using Abp.Domain.Repositories;
using MyCompanyName.AbpZeroTemplate.Authorization.Roles;
using MyCompanyName.AbpZeroTemplate.Authorization.Users;
using MyCompanyName.AbpZeroTemplate.Prm.Project;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;

namespace MyCompanyName.AbpZeroTemplate.Prm.Admin
{
    public class MailManager : AbpZeroTemplateDomainServiceBase
    {
        private Abp.Runtime.Session.IAbpSession AbpSession { get; set; }
        private RoleManager _roleManager;
        private UserManager _userManager;
        private IRepository<MailDefined, int> _mailDefinedRepository { get; set; }
        private IRepository<ProjectInfo, int> _projectInfoRepository { get; set; }
        private IRepository<UserRole, long> _userRoleRepository { get; set; }
        public IRepository<MailRecord, int> _mailRecordRepository { get; set; }
        public IRepository<ProjectTeam, int> _projectTeamRepository { get; set; }
        public IRepository<ProjectRoleInfo, int> _projectRoleInfoRepository { get; set; }

        public MailManager(
            IRepository<MailRecord, int> mailRecordRepository,
            IRepository<MailDefined, int> mailDefinedRepository,
            IRepository<ProjectTeam, int> projectTeamRepository,
            IRepository<UserRole, long> userRoleRepository,
            IRepository<ProjectInfo, int> projectInfoRepository,
            RoleManager roleManager,
            UserManager userManager,
            IRepository<ProjectRoleInfo, int> projectRoleInfoRepository)
        {
            _mailDefinedRepository = mailDefinedRepository;
            _mailRecordRepository = mailRecordRepository;
            _projectTeamRepository = projectTeamRepository;
            _projectRoleInfoRepository = projectRoleInfoRepository;
            _projectInfoRepository = projectInfoRepository;
            _roleManager = roleManager;
            _userManager = userManager;
            _userRoleRepository = userRoleRepository;
            AbpSession = Abp.Runtime.Session.NullAbpSession.Instance;
        }

        public void CreateMailRecord(
            Dictionary<string, string> dic,
            MailCatelog category,
            int projectId = 0)
        {
            List<long> toUserIds = new List<long>();
            List<string> tomails = new List<string>();

            var mailDefined = _mailDefinedRepository.GetAll().Where(x => x.KeyCatelog == category).SingleOrDefault();

            if (projectId > 0 && !string.IsNullOrEmpty(mailDefined.ProjectRoles))
            {
                List<int> projectRoles = mailDefined.ProjectRoles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)).ToList();
                var users = _projectTeamRepository.GetAll().Where(x => x.ProjectId == projectId).Where(x => projectRoles.Any(m => m == x.ProjectRoleId)).Select(x => x.UserId).ToList();
                toUserIds.AddRange(users);
            }

            //如果邮件定义中的系统角色不为空，把此系统角色中的人员取回来
            if (!string.IsNullOrEmpty(mailDefined.SystemRoles))
            {
                List<int> systemRoles = mailDefined.SystemRoles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)).ToList();
                var roles = _roleManager.Roles.Where(x => systemRoles.Contains(x.Id)).ToList();
                foreach (var item in roles)
                {
                    var userIds = _userRoleRepository.GetAll().Where(x => x.RoleId == item.Id).Select(m => m.UserId).ToList();
                    var users = _userManager.Users.Where(x => userIds.Any(m => m == x.Id)).ToList();
                    if (projectId > 0)
                    {
                        var p = _projectInfoRepository.Get(projectId);
                        switch (mailDefined.OptScope)
                        {
                            case MyCompanyName.AbpZeroTemplate.Prm.Authorization.ActionScope.Null:
                                users = new List<User>();
                                break;
                            case MyCompanyName.AbpZeroTemplate.Prm.Authorization.ActionScope.all:
                                break;
                            case MyCompanyName.AbpZeroTemplate.Prm.Authorization.ActionScope.business:
                                users = users.Where(x => x.BusinessId == p.BusinessId).ToList();
                                break;
                            case MyCompanyName.AbpZeroTemplate.Prm.Authorization.ActionScope.center:
                                users = users.Where(x => x.RdCenterId == p.RdCenterId).ToList();
                                break;
                            case MyCompanyName.AbpZeroTemplate.Prm.Authorization.ActionScope.room:
                                users = users.Where(x => x.LaboratoryId == p.LaboratoryId).ToList();
                                break;
                            default:
                                break;
                        }
                    }
                    if (users.Count > 0)
                    {
                        toUserIds.AddRange(users.Select(x => x.Id));
                    }
                }
            }
            //去掉重复的发送人
            toUserIds = toUserIds.Distinct().ToList();

            foreach (var toUserId in toUserIds)
            {
                string mail = _userManager.Users.Where(x => x.Id == toUserId).SingleOrDefault().EmailAddress;
                tomails.Add(mail);
            }

            if (!string.IsNullOrEmpty(mailDefined.Receivers))
            {
                List<string> _receivers = mailDefined.Receivers.Split(new char[] { ',', '；', ';', '，' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                tomails.AddRange(_receivers);
            }
            string body = mailDefined.Body;
            string subject = mailDefined.Subject;
            foreach (var item in dic)
            {
                body = body.Replace("[" + item.Key + "]", item.Value);
                subject = subject.Replace("[" + item.Key + "]", item.Value);
            }
            var record = new MailRecord()
            {
                Subject = subject,
                Body = body,
                IsSuccess = false,
                ErrorMsg = string.Empty,
                IsSend = false,
                Priority = mailDefined.Priority,
                Receivers = string.Join(",", tomails.Distinct())
            };
            _mailRecordRepository.Insert(record);
        }

        public void CreateInquiryTAMailRecord(
            string preSubject,
           Dictionary<string, string> dic,
           MailCatelog category,
           int receiverId)
        {
            List<long> toUserIds = new List<long>() { receiverId };
            List<string> tomails = new List<string>();
            _createMailRecord(preSubject, dic, category, toUserIds, tomails);
        }


        public void CreateProTaskMailRecord(
            string preSubject,
           Dictionary<string, string> dic,
           MailCatelog category,
           List<long> receiverIds)
        {
            List<long> toUserIds = new List<long>();
            toUserIds.AddRange(receiverIds);
            List<string> tomails = new List<string>();

            _createMailRecord(preSubject, dic, category, toUserIds, tomails);
        }

        private void _createMailRecord(string preSubject, Dictionary<string, string> dic, MailCatelog category, List<long> toUserIds, List<string> tomails)
        {
            var mailDefined = _mailDefinedRepository.GetAll().Where(x => x.KeyCatelog == category).SingleOrDefault();
            //如果邮件定义中的系统角色不为空，把此系统角色中的人员取回来
            if (!string.IsNullOrEmpty(mailDefined.SystemRoles))
            {
                List<int> systemRoles = mailDefined.SystemRoles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)).ToList();
                var roles = _roleManager.Roles.Where(x => systemRoles.Contains(x.Id)).ToList();
                foreach (var item in roles)
                {
                    var userIds = _userRoleRepository.GetAll().Where(x => x.RoleId == item.Id).Select(m => m.UserId).ToList();
                    var users = _userManager.Users.Where(x => userIds.Any(m => m == x.Id)).ToList();
                    if (users.Count > 0)
                    {
                        toUserIds.AddRange(users.Select(x => x.Id));
                    }
                }
            }
            //去掉重复的发送人
            toUserIds = toUserIds.Distinct().ToList();

            foreach (var toUserId in toUserIds)
            {
                string mail = _userManager.Users.Where(x => x.Id == toUserId).SingleOrDefault().EmailAddress;
                tomails.Add(mail);
            }

            if (!string.IsNullOrEmpty(mailDefined.Receivers))
            {
                List<string> _receivers = mailDefined.Receivers.Split(new char[] { ',', '；', ';', '，' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                tomails.AddRange(_receivers);
            }
            string body = mailDefined.Body;
            string subject = mailDefined.Subject;
            foreach (var item in dic)
            {
                body = body.Replace("[" + item.Key + "]", item.Value);
                subject = subject.Replace("[" + item.Key + "]", item.Value);
            }
            var record = new MailRecord()
            {
                Subject = preSubject + subject,
                Body = body,
                IsSuccess = false,
                ErrorMsg = string.Empty,
                IsSend = false,
                Priority = mailDefined.Priority,
                Receivers = string.Join(",", tomails.Distinct())
            };
            _mailRecordRepository.Insert(record);
        }


        public void SendMail(string smtpserver, string userName, string userPwd, string userDomain,
           string strfromemail, string strfromdisplayname)
        {
            var todos = _mailRecordRepository.GetAll().Where(x => x.IsSend == false).ToList();
            foreach (var item in todos)
            {
                List<string> _receivers = item.Receivers.Split(new char[] { ',', '；', ';', '，' }, StringSplitOptions.RemoveEmptyEntries).ToList();

                try
                {
                    SendMail(smtpserver, userName, userPwd, userDomain, strfromemail, strfromdisplayname, _receivers, item.Subject, item.Body);
                    item.IsSend = true;
                    item.IsSuccess = true;
                }
                catch (Exception ex)
                {

                    item.IsSend = true;
                    item.IsSuccess = false;
                    item.ErrorMsg = ex.Message;
                }
                _mailRecordRepository.Update(item);
            }
        }



        public void SendMail(string smtpserver, string userName, string userPwd, string userDomain,
           string strfromemail, string strfromdisplayname,
           List<string> strto,
           string subj, string bodys,
           string[] attpath = null)
        {
            Console.Write(string.Format("SendMail：{0},> {1}", string.Join(",", strto), subj));
            try
            {
                _SendMail(smtpserver, userName, userPwd, userDomain, strfromemail, strfromdisplayname, strto, subj, bodys, attpath);
                Console.WriteLine(" success！");
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.ToString());
            }
        }


        private static void _SendMail(string smtpserver, string userName, string userPwd, string userDomain, string strfromemail, string strfromdisplayname, List<string> strto, string subj, string bodys, string[] attpath)
        {

            // 定义 邮件
            MailMessage mailMessage = new MailMessage();

            // 收件人
            foreach (var item in strto)
            {
                if (IsEmail(item))
                {
                    mailMessage.To.Add(item);
                }
            }

            // 发件人
            mailMessage.From = new MailAddress(strfromemail, strfromdisplayname);


            mailMessage.Subject = subj;
            mailMessage.Body = bodys;
            if (attpath != null)
            {
                for (int i = 0; i < attpath.Length; i++)
                {
                    string text = attpath[i];
                    if (!string.IsNullOrEmpty(text) && System.IO.File.Exists(text))
                    {
                        mailMessage.Attachments.Add(new Attachment(text));
                    }
                }
            }
            mailMessage.SubjectEncoding = System.Text.Encoding.UTF8;
            mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
            mailMessage.IsBodyHtml = true;
            mailMessage.Priority = MailPriority.High;


            // 定义 smtp 服务器
            SmtpClient smtpClient = new SmtpClient();
            smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
            smtpClient.Host = smtpserver;
            smtpClient.Credentials = new System.Net.NetworkCredential(userName, userPwd, userDomain);
            smtpClient.Send(mailMessage);
        }



        /// <summary>
        /// 判断是否是邮箱地址
        /// </summary>
        /// <param name="str1">待判断的邮箱地址</param>
        /// <returns>true or false</returns>
        public static bool IsEmail(string str1)
        {
            if (str1 == null || str1 == string.Empty || str1.Length < 3) return false;
            return System.Text.RegularExpressions.Regex.IsMatch(str1, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");

        }


    }
}
